/*!
基于rust和sciter的redis桌面客户端工具
*/
// 关闭window下的黑窗口
// #![windows_subsystem = "windows"]
mod events;
mod redis_helper;
mod sqlite;
mod windows;
mod ws;

#[macro_use]
extern crate sciter;
#[macro_use]
extern crate lazy_static;

use crate::events::Event;
use sciter::Value;
use serde::{Deserialize, Serialize};
use std::io::{Read, Write};
use std::net;
use std::net::Ipv4Addr;
use std::result::Result::Ok;
use std::thread::spawn;
use std::time::Duration;
lazy_static! {
    /// 定义全局文件资源
    pub static ref RESOURCE: &'static [u8] = include_bytes!("resource.rc");
}
/// 主程序入口
fn main() {
    // 设置配置sciter
    sciter::set_options(sciter::RuntimeOptions::ScriptFeatures(
        sciter::SCRIPT_RUNTIME_FEATURES::ALLOW_SYSINFO as u8
            | sciter::SCRIPT_RUNTIME_FEATURES::ALLOW_FILE_IO as u8
            | sciter::SCRIPT_RUNTIME_FEATURES::ALLOW_SOCKET_IO as u8,
    ))
    .unwrap();
    sciter::set_options(sciter::RuntimeOptions::LogicalPixel(true)).unwrap();
    use std::sync::mpsc::channel;

    // 开发模式下打开sciter调试
    if cfg!(debug_assertions) {
        sciter::set_options(sciter::RuntimeOptions::DebugMode(true)).unwrap();
        let (tx, rx) = channel();
        std::thread::spawn(move || {
            ctrlc::set_handler(move || {
                let mut evt = events::Events {};
                evt.global_event("clear-trayIcon".to_string(), Value::null());
                tx.send(()).expect("Could not send signal on channel.");
            })
            .expect("Error setting Ctrl-C handler");
            rx.recv().expect("ev");
        });
    }
    spawn(|| ws::run());
    // 检查是否在运行
    crate::check_system_is_running();
    // 启动tray
    windows::service(*RESOURCE);
}
/// 采用tcp的方式进行软件运行校验
fn check_system_is_running() {
    // 请求一下是否启动了tcp
    fn send() {
        // 定义开始端口
        let mut port = 19213;
        // 最多循环10次
        loop {
            if port > 19223 {
                break;
            }
            let addr = net::SocketAddr::new(net::IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)), port);
            // 启动tcp连接
            if let Ok(mut stream) =
                net::TcpStream::connect_timeout(&addr, Duration::from_micros(100))
            {
                // 写入询问数据
                stream.write("{\"check\":true}".as_bytes()).unwrap_or(0);
                // 创建一个buffer
                let mut buf = [0; 256];
                // 读取数据到buffer
                stream.read(&mut buf).unwrap_or(0);

                let mut data = Vec::new();
                // 踢出无用数据
                for item in buf.iter() {
                    if *item == 0 {
                        break;
                    }
                    data.push(*item);
                }
                // 创建消息对象，serde_json方便反序列化
                #[derive(Debug, Deserialize, Serialize)]
                struct Msg {
                    status: bool,
                }
                if let Ok(res) = serde_json::from_slice::<Msg>(&data) {
                    if res.status {
                        std::process::exit(0);
                    }
                }
                // 结束跳槽循环
                break;
            } else {
                port += 1;
            }
        }
    }
    send();
    // 创建tcp服务
    fn server() {
        // 定义开始端口
        let mut port = 19213;
        // 最多循环10次
        loop {
            if port > 19223 {
                break;
            }
            // 监听tcp端口
            if let Ok(listener) = net::TcpListener::bind(format!("127.0.0.1:{}", port)) {
                loop {
                    // tcp确认
                    for conn in listener.accept() {
                        // 起一个线程来处理避免阻塞
                        std::thread::spawn(move || {
                            // 同上
                            let mut stream = conn.0;
                            let mut buf = [0; 256];
                            stream.read(&mut buf).unwrap_or(0);
                            let mut data = Vec::new();
                            for item in buf.iter() {
                                if *item == 0 {
                                    break;
                                }
                                data.push(*item);
                            }

                            #[derive(Debug, Deserialize, Serialize)]
                            struct Msg {
                                check: bool,
                            }
                            if let Ok(res) = serde_json::from_slice::<Msg>(&data) {
                                if res.check {
                                    // sciter发送一个全局事件
                                    let mut evt = events::Events {};
                                    evt.global_event(format!("show-main"), Value::null());
                                    // 返回响应，让重复启动那个服务结束
                                    stream.write("{\"status\":true}".as_bytes()).unwrap_or(0);
                                }
                            };
                        });
                    }
                }
            } else {
                port += 1
            }
        }
    }
    // 启动服务
    std::thread::spawn(move || {
        server();
    });
}
